#include <iostream>
#include <memory>
class Car{
    public:
        using ptr = std::shared_ptr<Car>;
        void show()
        {
            std::cout<<"Brand " << _brand <<std::endl;
            std::cout<<"Engine " << _engine <<std::endl;
            std::cout<<"Wheel " << _wheel <<std::endl;
            std::cout<<"Petrol " << _petrol <<std::endl;
        }
        Car(const std::string& brand,const std::string& engine,const std::string& wheel,const std::string& petrol):
        _brand(brand),_engine(engine),_wheel(wheel),_petrol(petrol){}
    private:
        std::string _brand;
        std::string _engine;
        std::string _wheel;
        std::string _petrol;
};
class CarBuilder{
    public:
        using ptr = std::shared_ptr<CarBuilder>;
        Car::ptr build(){
            return std::make_shared<Car>(_brand,_engine,_wheel,_petrol);
        }
        CarBuilder& setBrand(const std::string& brand){ 
            _brand = brand;
            return *this;
        }
        CarBuilder& setEngine(const std::string& engine){
            _engine = engine;
            return *this;
        }
        CarBuilder& setWheel(const std::string& wheel){ 
            _wheel = wheel;
            return *this;
        }
        CarBuilder& setPetrol(const std::string& petrol){
            _petrol = petrol;
            return *this;
        }
    private:
        std::string _brand  = "bench";
        std::string _engine = "OEM";
        std::string _wheel = "Michelin";
        std::string _petrol = "Sinopec";
};

int main()
{
    CarBuilder::ptr builder = std::make_shared<CarBuilder>();
    Car::ptr car1 = builder->build();
    Car::ptr car2 = builder->setBrand("Laos").setEngine("88").setWheel("999").build();
    car1->show();
    car2->show();
    return 0;
}